package com.zyk.scaffold.oauth.framework.defaults;

import com.zyk.scaffold.oauth.framework.constants.OauthConstants;
import com.zyk.scaffold.oauth.framework.domain.AuthorizationDetails;
import com.zyk.scaffold.oauth.framework.domain.OauthContext;
import com.zyk.scaffold.oauth.framework.interfaces.ITokenConvert;
import org.apache.commons.lang3.ArrayUtils;

import java.util.*;

public class DefaultTokenConvert implements ITokenConvert {
    private List<ITokenConvert> lstAccessTokenConvert = new ArrayList();
    private List<ITokenConvert> lstRefreshTokenConvert = new ArrayList();

    @Override
    public AuthorizationDetails convert(OauthContext context) {
        Map<String, Object> accessTokenConvertData = new HashMap<>(16);
        Map<String, Object> refreshTokenConvertData = new HashMap<>(16);
        convert(context, accessTokenConvertData);
        refreshTokenConvertData.putAll(accessTokenConvertData);
        for (ITokenConvert tokenConvert: lstAccessTokenConvert) {
            tokenConvert.convert(context, accessTokenConvertData);
        }
        String[] grantTypes = context.getClientDetails().getAuthorizedGrantTypes();
        if(ArrayUtils.isNotEmpty(grantTypes) && Arrays.stream(grantTypes).anyMatch(grantType -> "refresh_token".equals(grantType))){
            for (ITokenConvert tokenConvert: lstRefreshTokenConvert) {
                tokenConvert.convert(context, refreshTokenConvertData);
            }
        }
        return new AuthorizationDetails(accessTokenConvertData, refreshTokenConvertData);
    }

    @Override
    public void convert(OauthContext context, Map<String, Object> convertData) {
        convertData.put(OauthConstants.TokenData.KEY_IS_ACCOUNT, context.getUserDetails().getAccount());
        convertData.put(OauthConstants.TokenData.KEY_IS_CLIENT_ID, context.getClientDetails().getClientId());
        convertData.put(OauthConstants.TokenData.KEY_IS_PUBLIC_KEY, context.getClientDetails().getPublicKey());
        convertData.put(OauthConstants.TokenData.KEY_IS_SCOPES, context.getClientDetails().getScopes());
    }

    @Override
    public boolean registerAccessTokenConvert(ITokenConvert tokenConvert) {
        if(null == tokenConvert){
            return Boolean.FALSE;
        }
        lstAccessTokenConvert.add(tokenConvert);
        return true;
    }

    @Override
    public boolean registerRefreshTokenConvert(ITokenConvert tokenConvert) {
        if(null == tokenConvert){
            return Boolean.FALSE;
        }
        lstRefreshTokenConvert.add(tokenConvert);
        return true;
    }
}
